//
//  ApiManager.swift
//  JWBaseLib
//
//  Created by 周季伟 on 2017/12/12.
//  Copyright © 2017年 周季伟. All rights reserved.
//

import Alamofire
import SwiftyJSON

public typealias RequestIndex = Int
public class ApiManager {
    public static let shared = ApiManager()
    private init() {}
    var router = Router()
    var cache = Cache()
    lazy var alamofireManager: SessionManager = {
        let configuration = URLSessionConfiguration.default
        configuration.timeoutIntervalForRequest = 20
        return SessionManager(configuration: configuration)
    }()
    var currentIndex: RequestIndex = 0              // 当前的索引值，每当新的请求进入，就+1
    var requestPool = [RequestIndex: Request]()     // 保存所有的网络请求
}

extension ApiManager {
    func request(urlString: String,
                 method: HTTPMethod = .get,
                 parameters: [String: Any]? = nil,      // 可选，请求参数，默认为空
        encoding: ParameterEncoding = URLEncoding.default,   // 可选，编码方式，默认为json
        headers: [String: String]? = nil,      // 可选，Header，默认为空
        completion: ((ApiResult<JSON>) -> Void)?) -> RequestIndex {
        let request = alamofireManager.request(router.resourceBy(urlString), method: method, parameters: parameters, encoding: encoding, headers: headers).responseJSON { (response) in
            let apiResult: ApiResult<JSON>
            switch response.result {
            case .success(let responseValue):
                switch response.response!.statusCode {
                case 200..<300:
                    apiResult = ApiResult.success(JSON(responseValue))
                    self.cache.save(value: responseValue as! [String: AnyObject], for: self.cache.cahceKey(for: urlString, method: method, parameters: parameters, headers: headers))
                default:
                    apiResult = ApiResult.failure(ApiError.http(response.response!.statusCode))
                }
            case .failure(let error):
                apiResult = ApiResult.failure(ApiError.library(error))
            }
            completion?(apiResult)
        }
        currentIndex += 1
        requestPool[currentIndex] = request
        return currentIndex
    }
    // 从缓存中读取
    func loadCache(urlString: String,
                   method: HTTPMethod = .get,
                   parameters: [String: Any]? = nil,
                   headers: [String: String]? = nil) -> ApiResult<JSON> {
        let key = cache.cahceKey(for: urlString, method: method, parameters: parameters, headers: headers)
        if let value = cache.load(for: key) {
            return ApiResult.success(JSON(value))
        }
        return ApiResult.failure(ApiError.noCache)
    }
}

extension ApiManager {
    func cancel(at index: RequestIndex) {
        requestPool.removeValue(forKey: index)?.cancel()
    }
    func cancel(some: [RequestIndex]) {
        some.forEach { (index) in
            cancel(at: index)
        }
    }
    func cancelAll() {
        requestPool.forEach { (index, _) in
            cancel(at: index)
        }
    }
}
